package com.plian.system.service.sys.token;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.plian.Tools.Tools;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.config.exception.MyRuntimeException;
import com.plian.system.dao.sys.user.UserDao;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ObjResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class TokenService {
    @Autowired
    UserDao userDao;

    public String getToken(String userId, String orgId, String password){
        String token = null;
        try {
            Date start = new Date();
            long currentTime = System.currentTimeMillis() + 60* 60 * 1000;//一小时有效时间
            Date end = new Date(currentTime);
            if(Tools.notEmpty(orgId)){
                token = JWT.create().withAudience(userId, orgId).withIssuedAt(start).withExpiresAt(end)
                        .sign(Algorithm.HMAC256(password));
            }else{
                token = JWT.create().withAudience(userId).withIssuedAt(start).withExpiresAt(end)
                        .sign(Algorithm.HMAC256(password));
            }

        } catch (Exception e){
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return token;
    }

    public String getLongToken(String userId, String orgId, String password) {
        String token = null;
        try {
            Date start = new Date();
            long currentTime = System.currentTimeMillis() + 60* 60 * 1000*24*14;//半月有效时间
            Date end = new Date(currentTime);
            if(Tools.notEmpty(orgId)){
                token = JWT.create().withAudience(userId, orgId).withIssuedAt(start).withExpiresAt(end)
                        .sign(Algorithm.HMAC256(password));
            }else{
                token = JWT.create().withAudience(userId).withIssuedAt(start).withExpiresAt(end)
                        .sign(Algorithm.HMAC256(password));
            }
        } catch (Exception e){
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return token;
    }

    public String getToken(PageData pd) {
        String token = null;
        try {
            Date start = new Date();
            long currentTime = System.currentTimeMillis() + 60* 60 * 1000;//一小时有效时间
            Date end = new Date(currentTime);
            String aduience=pd.getString("id");
            if(Tools.notEmpty(pd.getString("orgId"))){
                token = JWT.create().withAudience(aduience,pd.getString("orgId")).withIssuedAt(start).withExpiresAt(end)
                        .sign(Algorithm.HMAC256(pd.getString("password")));
            }else{
                token = JWT.create().withAudience(aduience).withIssuedAt(start).withExpiresAt(end)
                        .sign(Algorithm.HMAC256(pd.getString("password")));
            }

        } catch (Exception e){
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return token;
    }
    public String getLongToken(PageData pd) {
        String token = null;
        try {
            Date start = new Date();
            long currentTime = System.currentTimeMillis() + 60* 60 * 1000*24*14;//半月有效时间
            Date end = new Date(currentTime);
            String aduience=pd.getString("id");
            if(Tools.notEmpty(pd.getString("orgId"))){
                token = JWT.create().withAudience(aduience,pd.getString("orgId")).withIssuedAt(start).withExpiresAt(end)
                        .sign(Algorithm.HMAC256(pd.getString("password")));
            }else{
                token = JWT.create().withAudience(aduience).withIssuedAt(start).withExpiresAt(end)
                        .sign(Algorithm.HMAC256(pd.getString("password")));
            }
        } catch (Exception e){
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return token;
    }

    /**
     * 刷新token
     * @return
     */
    public ObjResult refreshToken(PageData pd){
        ObjResult objResult;
        String longToken=pd.getString("longToken");
        try {
            //判断有无Token
            if(Tools.isEmpty(longToken)){
                ObjResult obj=new ObjResult(CommonCode.UNTOKEN);
                throw new MyRuntimeException(obj);
            }
            // 获取 token 中的 user id
            List<String> Audience;
            try {
                Audience = JWT.decode(longToken).getAudience();
            }catch (JWTDecodeException e){
                ObjResult obj=new ObjResult(CommonCode.UNTOKEN);
                log.error(ExceptionUtils.getFullStackTrace(e));
                throw new MyRuntimeException(obj);
            }
            if(Audience==null || Audience.size()<=0){
                ObjResult obj=new ObjResult(CommonCode.UNAUTHORISE);
                throw new MyRuntimeException(obj);
            }
            String userid=Audience.get(0);
            PageData user= userDao.findbyid(userid);
            if (user == null) {
                ObjResult obj=new ObjResult(CommonCode.UNTOKEN);
                throw new MyRuntimeException(obj);
            }
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getString("password"))).build();
            try {
                jwtVerifier.verify(longToken);
            } catch (JWTVerificationException e) {
                log.error(ExceptionUtils.getFullStackTrace(e));
                ObjResult obj=new ObjResult(CommonCode.UNTOKEN);
                throw new MyRuntimeException(obj);
            }
            PageData p_token=new PageData();
            if(Audience.size()>=2){
                p_token.put("orgId", Audience.get(1));
            }
            p_token.put("type", user.getString("type"));
            p_token.put("username", user.getString("username"));
            p_token.put("password", user.getString("password"));
            p_token.put("id", user.getString("id"));
            p_token.put("isInitialPassword", user.getInteger("isInitialPassword"));
            objResult=new ObjResult(CommonCode.SUCCESS);
            PageData p=new PageData();
            p.put("token",getToken(p_token));
            objResult.setPageData(p);
            return objResult;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            throw  new MyRuntimeException();
        }

    }
}
